package edu.ruc.cluster.ui;

//import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileWriter;
import java.io.File;
import java.io.IOException;

import javax.swing.BoxLayout;

import java.util.Set;
import java.util.HashSet;
//import java.util.Iterator;
//import java.util.List;
//import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ImageIcon;
import javax.swing.border.BevelBorder;
import javax.swing.border.SoftBevelBorder;
import javax.swing.border.TitledBorder;

import edu.ruc.cluster.util.Const;
import edu.ruc.cluster.util.DefaultLogHandler;
import edu.ruc.cluster.util.ColumnLayout;
import edu.ruc.cluster.util.ImageLabel;
import edu.ruc.cluster.util.PropertyRetrieval;

@SuppressWarnings("serial")
public class MachineListPane extends JPanel {
	
//	private JLabel welcome = null;
	private JPanel slave = null;
	private JPanel master = null;
	private JPanel checkmaster = null;
	private JPanel checkslave = null;
	
	private JTextField masterip = null;
	private JTextField mastername = null;
	private JTextArea slaveip = null;
	private JTextArea slavename = null;
//	private JScrollPane slaveip = null;
//	private JScrollPane slavename = null;
	private JLabel masteripcheck = null;
	private JLabel masternamecheck = null;
	private JLabel slaveipcheck = null;
	private JLabel slavenamecheck = null;
//	private List<JLabel> slaveipcheck = null;
//	private List<JLabel> slavenamecheck = null;
	private JLabel numberInfo = null;
	
	private JButton check = new JButton("check");
	
	private DefaultLogHandler lh = null;
	
	private ImageIcon right = null;
	private ImageIcon wrong = null;
	
	private static int nrows = 5;
	private static int ncolums = 15;
	
	private boolean readyForNext = true;
	
	String[] ips = null ;
	String[] names = null ;
	private ActionListener b1 = new ActionListener(){
		public void actionPerformed(ActionEvent e){
			lh.info("called on check");
			System.out.println("a");
			checkInput();
		}
	};
	public MachineListPane(){
		
		lh = DefaultLogHandler.getInstance();
		
		master = new JPanel(new ColumnLayout());				
		master.setBorder(new TitledBorder("master"));
		masterip = new JTextField(ncolums);
		mastername = new JTextField(ncolums);
		masterip.setBorder(new TitledBorder("ip"));
		mastername.setBorder(new TitledBorder("name"));
		master.add(masterip);
		master.add(mastername);
		
		slave = new JPanel(new ColumnLayout());
		slaveip = new JTextArea(nrows, ncolums);
		slavename = new JTextArea(nrows, ncolums);
		slaveip.setBorder(new SoftBevelBorder(BevelBorder.LOWERED));
		slavename.setBorder(new SoftBevelBorder(BevelBorder.LOWERED));
		JScrollPane scrollip = new JScrollPane(slaveip);
		JScrollPane scrollname = new JScrollPane(slavename);
		scrollip.setBorder(new TitledBorder("ip"));
		scrollname.setBorder(new TitledBorder("name"));
		slave.setBorder(new TitledBorder("slave"));
		slave.add(scrollip);
		slave.add(scrollname);
		
		checkmaster = new JPanel(new ColumnLayout());
		checkmaster.setBorder(new TitledBorder(" "));
		
		checkslave = new JPanel(new ColumnLayout());
		checkslave.setBorder(new TitledBorder(" "));
		numberInfo = new JLabel(" ");
		
		lh.info("before check button");
//		check = new JButton("check");  
		check.addActionListener(b1);
		
		this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
//		this.add(welcome);
		this.add(master);
		this.add(checkmaster);
		this.add(slave);
		this.add(checkslave);
		this.add(check);
		this.setVisible(true);
	}

	public void checkInput(){
		
		lh.info("checking input...");
		
		right = new ImageIcon(this.getClass().getResource(Const.RIGHT_ICON_PATH), "right icon");
		wrong = new ImageIcon(getClass().getResource(Const.WRONG_ICON_PATH), "wrong icon");
		
		boolean masteripb = true;
		boolean masternameb = true;
		boolean slaveipb = true;
		boolean slavenameb = true;
		
		readyForNext = true;
		String ip = masterip.getText().trim();
//		System.out.println(ip);
		if( checkIp(ip) == false){
			//TODO: some feedback on UI 
//			System.out.println("false");
//			masteripcheck.setText("Error");
//			masteripcheck = new ImageLabel(wrong);
			readyForNext = false;
			masteripb = false;
		}
		if(mastername.getText().isEmpty()){
			masternameb = false;
			readyForNext = false;
		}
//		else{
//			masteripcheck.setText("OK");
//			masternamecheck.setText("OK");
//			masteripcheck = new ImageLabel(right);
//		}
		
		ips = slaveip.getText().split("\\s");
		names = slavename.getText().split("\\s");
		if(ips.length != names.length){
			//TODO: massage dialog
			System.out.println(ips.length + " " + names.length);
			numberInfo.setText("Number error");
			readyForNext = false;
		}else{
			numberInfo.setText(" ");
		}
		
//		slaveipcheck.clear();
//		slavenamecheck.clear();
		Set<String> checkDup = new HashSet<String>();
		
		for(int i = 0 ; i < ips.length ; i ++){
			
			if(checkIp(ips[i]) == false || checkDup.add(ips[i]) == false){
//				slaveipcheck.add(new ImageLabel(wrong));
				readyForNext = false;
				slaveipb = false;
				break;
			}
//			else
//				slaveipcheck.add(new ImageLabel(right));
			/*
			if( checkIp(ips[i], eh, lh) == false){
				//TODO: some feedback on UI
				label.setText("Err");				
				readyForNext = false;
			}
			if(checkDup.add(ips[i]) == false){
				label.setText("Dup " + label.getText());
				
			}
			if(label.getText().equals("") == true){
				slaveipcheck.add(new JLabel("OK"));
			}
			slaveipcheck.add(label);
			*/
		}
		checkDup.clear();
			// Output: 1?????????????????????????????????
		lh.info("names.length: " + names.length);
		for(int i = 0 ; i < names.length ; i ++){
			if( checkDup.add(names[i]) == false){
				//TODO: duplicate names for ip
//				slavenamecheck.add(new JLabel("Dup"));
//				slavenamecheck.add(new ImageLabel(wrong));
				readyForNext = false;
				slavenameb = false;
				break;
			}
//			else{
//				slavenamecheck.add(new JLabel("OK"));
//				slavenamecheck.add(new ImageLabel(right));
//			}
		}
		if(slavename.getText().isEmpty()){
			slavenameb = false;
			readyForNext = false;
		}
		fillCheckPanel(masteripb, masternameb, slaveipb, slavenameb);
		
	}
	private void fillCheckPanel(boolean masterip, boolean mastername, boolean slaveip, boolean slavename){
		
		checkmaster.removeAll();
		checkslave.removeAll();
		
		masteripcheck = masterip == true? new ImageLabel(right) : new ImageLabel(wrong);
		masternamecheck = mastername == true ? new ImageLabel(right) : new ImageLabel(wrong);
		
		slaveipcheck = slaveip == true ? new ImageLabel(right) : new ImageLabel(wrong);
		slavenamecheck = slavename == true ? new ImageLabel(right) : new ImageLabel(wrong);
		
		checkmaster.add(new JLabel(" "));
		checkmaster.add(masteripcheck);
		checkmaster.add(new JLabel(" "));
		checkmaster.add(masternamecheck);
		
		checkslave.add(numberInfo);
		checkslave.add(slaveipcheck);
		JTextArea tmp = new JTextArea(nrows, 1);
		tmp.setVisible(false);
		checkslave.add(tmp);
		checkslave.add(slavenamecheck);
//		Iterator<JLabel> iter = slaveipcheck.iterator();
//		int count = 0;
//		while(iter.hasNext()){
//			checkslave.add(iter.next());
//			count++;
//		}
//		while(count < 3){
//			checkslave.add(new JLabel(" "));
//			count ++;
//		}
		
//		iter = slavenamecheck.iterator();
//		while(iter.hasNext()){
//			checkslave.add(iter.next());
//		}
		this.updateUI();
	}
	boolean checkIp(String ip){

		String[] strs = ip.split("\\.");
		if(strs.length != 4){
			return false;
		}
		for(int i = 0 ; i < strs.length ; i ++){
			try{
				int subip = Integer.parseInt(strs[i]);
				if(subip>=0 && subip<=255)
					continue;
				else{
					lh.error(this.getName() + "ip error " + strs[i]);
					return false;
				}
			}catch(NumberFormatException e){
//				eh.handle(e);
				lh.error(this.getName(), e);
				return false;
			}
		}
		return true;
	}
	
	public boolean nextReady(){
		return readyForNext;
	}
	public void store(){
		try{
			boolean both = false;
			FileWriter writor = new FileWriter(new File(Const.IP_LIST_FILE));
			String str1 = masterip.getText().trim() + Const.LINE_SEPERATOR + mastername.getText().trim() + "\n";
			writor.write(str1);
			for(int i = 0 ; i < ips.length ; i ++){
				String str2 = ips[i] + Const.LINE_SEPERATOR + names[i]  + "\n";
				if(str2.equals(str1) == false)
					writor.write(str2);
				else{
					both = true;
				}
			}
			writor.flush();
			writor.close();
			
			PropertyRetrieval pr = new PropertyRetrieval(Const.CONFIG_FILE);
			pr.putString(Const.MASTERS_TAG, mastername.getText().trim());
			pr.putString(Const.MASTER_IS_SLAVE_TAG, String.valueOf(both));
			
		}catch(IOException e){
			lh.error(this.getName(), e);
		}
	}
	
}
